package br.ufpa.cbcc2007.dikemon.map;

import java.util.Vector;

import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.game.TiledLayer;

import br.ufpa.cbcc2007.dikemon.engine.Engine;
import br.ufpa.cbcc2007.dikemon.map.actors.Hero;

//Classe que representa uma visão estática de um mapa carregado.
public class Map{
	Vector actualizables;		//Lista dos sprites que implementam Actualizable
	Vector collideables;		//Lista dos sprites que implementam Collidable
	LayerManager layerManager;	//Gerenciador de camadas
	TiledLayer bottom;			//Camada Inferior
	TiledLayer middle;			//Camada do meio (está camada é colide com os Sprites
	TiledLayer top;				//Camada Superior
	int offsetY;				//Deslocamento do mapa a partir da origem, em pixels
	int offsetX;				//Deslocamento do mapa a partir da origem, em pixels
	Sprite spriteFollowed;		//Qual Sprite está sendo seguido. Geralmente é do tipo Hero
	int size;					//Qual o tamanho da tela. O jogo supõe uma tela quadrada.
	boolean follow;				//Flag, que indica, se o spriteFollowed será ou não de fato seguido.
	
	//Contrutor
	public Map(int columns, int rows, Image image, int tileWidth, int tileHeight){
		actualizables = new Vector();
		collideables = new Vector();
		layerManager = new LayerManager();
		top = new TiledLayer(columns, rows, image, tileWidth, tileHeight);
		middle = new TiledLayer(columns, rows, image, tileWidth, tileHeight);
		bottom = new TiledLayer(columns, rows, image, tileWidth, tileHeight);
		layerManager.append(top);
		layerManager.append(middle);
		layerManager.append(bottom);
		offsetX = offsetY = 0;
		setSpriteFollowed(null);
		follow = true;
		size = 11*Engine.TILESIZE;
		layerManager.setViewWindow(offsetX, offsetY, size, size);
	}
	
	//Inclui um Sprite. Este pode ser destacado e incluído em uma lista especial se implantar uma classe ou interface
	// que especial.
	public void append(Sprite sprite) {
		layerManager.insert(sprite, 1);		//Insere um sprite logo abaixo do topo. Como a posições inferiores sempre
											//se sobrepõe as superiores, o último Sprite inserido sempre ficará acima
											//todos os outros sprites e das camadas bottom e middle, mas nunca estará
											//acima da camada topo
		if( sprite instanceof Actualizeable) actualizables.addElement(sprite);
		if( sprite instanceof Collideable) collideables.addElement(sprite);
		if( sprite instanceof Hero) setSpriteFollowed(sprite);
	}

	public TiledLayer getBottom() {
		return bottom;
	}
	
	public TiledLayer getMiddle(){
		return middle;
	}

	public TiledLayer getTop() {
		return top;
	}

	/**
	 * @param spriteFollowed the spriteFollowed to set
	 */
	public void setSpriteFollowed(Sprite spriteFollowed) {
		this.spriteFollowed = spriteFollowed;
	}

	/**
	 * @return the spriteFollowed
	 */
	public Sprite getSpriteFollowed() {
		return spriteFollowed;
	}

	public boolean isFollow() {
		return follow;
	}

	public void setFollow(boolean follow) {
		this.follow = follow;
	}

}
